﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace UIElements
{
    /// <summary>
    /// Performs basic menu operations such as drawing a menu and managing menu items.
    /// </summary>
    public class Menu
    {
        public List<MenuItem> lMenuItems { get; set; }
        private SpriteBatch spriteBatch;
        private GraphicsDevice graphicsDevice;
        private ButtonState lastCursorState;
        public MenuItem lastSelectedItem;

        public Menu(GraphicsDevice myGraphicsDevice, SpriteBatch mySpriteBatch)
        {
            spriteBatch = mySpriteBatch;
            graphicsDevice = myGraphicsDevice;
            lMenuItems = new List<MenuItem>();
            lastCursorState = new ButtonState();

        }

        public void Update()
        {



        }

        /// <summary>
        /// Checks whether any item in the menu has been clicked and changes the background image of the item if the mouse is over it.
        /// </summary>
        /// <param name="cursorPosition"></param>
        /// <param name="lmb"></param>
        /// <returns></returns>
        public MenuItem checkMenuItemState(Vector2 cursorPosition, ButtonState lmb)
        {
            foreach (MenuItem item in lMenuItems)
            {
                if (item.MouseIsOverMenuItem(cursorPosition))
                {

                    if ((lastCursorState == ButtonState.Pressed) && (lmb == ButtonState.Released) && (item == lastSelectedItem))
                    {
                        return item;
                    }

                    lastSelectedItem = item;

                }

            }

            lastCursorState = lmb;

            return null;

        }

        /// <summary>
        /// Sends a message to each item in the menu telling it to draw itself
        /// </summary>
        public void DrawMenu()
        {
            float xOffsetText, yOffsetText;
            Rectangle rectSafeArea;
            rectSafeArea = graphicsDevice.Viewport.TitleSafeArea;

            xOffsetText = rectSafeArea.X;
            yOffsetText = rectSafeArea.Y;

            float menuItemYOffset = 0;

            foreach (MenuItem item in lMenuItems)
            {
                Vector2 itemPosition = new Vector2(xOffsetText, yOffsetText);
                itemPosition.Y += menuItemYOffset;

                item.Position = itemPosition;
                item.Draw();

                menuItemYOffset += item.CurrentImage.Height;
            }


        }

        /// <summary>
        /// Sends a message to each item in the menu telling it to draw itself at the given position
        /// </summary>
        /// <param name="StartPosition"></param>
        public void DrawMenu(Vector2 StartPosition)
        {
            float xOffsetText, yOffsetText;
            Rectangle rectSafeArea;
            rectSafeArea = graphicsDevice.Viewport.TitleSafeArea;

            xOffsetText = rectSafeArea.X + StartPosition.X;
            yOffsetText = rectSafeArea.Y + StartPosition.Y;

            float menuItemYOffset = 0;

            foreach (MenuItem item in lMenuItems)
            {
                Vector2 itemPosition = new Vector2(xOffsetText, yOffsetText);
                itemPosition.Y += menuItemYOffset;

                item.Position = itemPosition;
                item.Draw();

                menuItemYOffset += item.CurrentImage.Height;
            }


        }



    }

    /// <summary>
    /// Represents an item of a menu.
    /// </summary>
    public class MenuItem
    {
        public string sText { get; set; }
        private Texture2D BackImage { get; set; }
        private Texture2D SelBackImage { get; set; }
        public SpriteFont itemFont { get; set; }
        private GraphicsDevice graphicsDevice;
        private SpriteBatch spriteBatch;
        public Vector2 Position { get; set; }
        public Texture2D CurrentImage { get; set; }


        public MenuItem(string myText, Texture2D myBackImage, Texture2D mySelBackImage, SpriteFont myFont, GraphicsDevice myGraphicsDevice, SpriteBatch mySpriteBatch)
        {
            sText = myText;
            BackImage = myBackImage;
            SelBackImage = mySelBackImage;
            itemFont = myFont;
            spriteBatch = mySpriteBatch;
            graphicsDevice = myGraphicsDevice;
            CurrentImage = BackImage;
        }

        public void Update()
        {

        }

        /// <summary>
        /// Draw the menu item
        /// </summary>
        public void Draw()
        {

            Vector2 strSize = itemFont.MeasureString(sText);

            float textxoffset = (BackImage.Width - strSize.X) / 2;
            float textyoffset = (BackImage.Height - strSize.Y) / 2;

            Vector2 textOffset = new Vector2(textxoffset, textyoffset);

            Vector2 textPosition = new Vector2();
            textPosition = textOffset + Position;

            spriteBatch.Draw(CurrentImage, Position, Color.White);
            spriteBatch.DrawString(itemFont, sText, textPosition, Color.White);
        }

        /// <summary>
        /// Check if the mouse is over the menu item and if it is, changes the background texture.
        /// </summary>
        /// <param name="cursorPosition"></param>
        /// <returns></returns>
        public Boolean MouseIsOverMenuItem(Vector2 cursorPosition)
        {
            Rectangle textureRect = new Rectangle((int)Position.X, (int)Position.Y, BackImage.Width, BackImage.Height);

            if (textureRect.Contains((int)cursorPosition.X, (int)cursorPosition.Y))
            {
                CurrentImage = SelBackImage;
                return true;
            }
            else
            {
                CurrentImage = BackImage;
                return false;
            }
        }


    }
    //public class Control
    //{
    //    public string text { get; set; }

    //    public string name { get; set; }

    //    public Boolean enabled { get; set; } 

    //    public Color color { get; set; }

    //    public Vector2 position { get; set; }

    //    public Vector2 size { get; set; }

    //    public SpriteFont font { get; set; }

    //    public Control()

    //    :this(Vector2.Zero)

    //    {

    //    }

    //    public Control(Vector2 myPosition)
    //    {
    //        position = myPosition;

    //        text = @"";

    //        name = @"";

    //        enabled = true;

    //        color = Color.White;
    //    }

    //    public virtual void Update(float elapsedTime)
    //    {

    //    }

    //    public virtual void UpdateInput(/*InputState input*/)
    //    {

    //    }

    //    public virtual void Draw(SpriteBatch spriteBatch)
    //    {

    //    }



    //}

    //public class ControlManager
    //{
    //    Dictionary<string, Control> controls = new Dictionary<string, Control>();

    //    void AddControl(Control newControl)
    //    {
    //        controls.Add(newControl.name, newControl);

    //    }
    //    void RemoveControl(string sControlToRemove)
    //    {
    //        controls.Remove(sControlToRemove);

    //    }

    //    public void Update(float elapsedTime)
    //    {

    //        foreach (var control in controls)
    //        {

    //            control.Value.Update(elapsedTime);

    //        }

    //    }

    //    public void UpdateInput(/*InputState input*/)
    //    {

    //        foreach (var control in controls)
    //        {

    //            control.Value.UpdateInput(input);

    //        }

    //    }

    //    public void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
    //    {

    //        foreach (var control in controls)
    //        {

    //            control.Value.Draw(spriteBatch);

    //        }

    //    }
}
